home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter8 / isohex8_2 / isohex8_2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-27  |  13.4 KB  |  564 lines

  1. /*****************************************************************************
  2. IsoHex8_2.cpp
  3. Ernest S. Pazera
  4. 24MAY2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Needs ddraw.lib, dsound.lib, winmm.lib and dxguid.lib
  7. Needs GDICanvas.h/cpp
  8. Needs DDFuncs.h/cpp
  9. Needs WAVLoader.h/cpp
  10. Needs dsound.h and mmsystem.h
  11. *****************************************************************************/
  12.  
  13. //////////////////////////////////////////////////////////////////////////////
  14. //INCLUDES
  15. //////////////////////////////////////////////////////////////////////////////
  16. #define WIN32_LEAN_AND_MEAN  
  17.  
  18. #include <windows.h>   
  19. #include "GDICanvas.h"
  20. #include "ddraw.h"
  21. #include "DDFuncs.h"
  22. #include "mmsystem.h"
  23. #include "dsound.h"
  24. #include "WAVLoader.h"
  25.  
  26. //////////////////////////////////////////////////////////////////////////////
  27. //DEFINES
  28. //////////////////////////////////////////////////////////////////////////////
  29. //name for our window class
  30. #define WINDOWCLASS "ISOHEX8"
  31. //title of the application
  32. #define WINDOWTITLE "IsoHex 8-2"
  33.  
  34. //////////////////////////////////////////////////////////////////////////////
  35. //PROTOTYPES
  36. //////////////////////////////////////////////////////////////////////////////
  37. bool Prog_Init();//game data initalizer
  38. void Prog_Loop();//main game loop
  39. void Prog_Done();//game clean up
  40.  
  41. //enumeration functions
  42. HRESULT WINAPI EnumModesCallbackCount(LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext);
  43. HRESULT WINAPI EnumModesCallbackList(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext);
  44.  
  45. //////////////////////////////////////////////////////////////////////////////
  46. //GLOBALS
  47. //////////////////////////////////////////////////////////////////////////////
  48. HINSTANCE hInstMain=NULL;//main application handle
  49. HWND hWndMain=NULL;//handle to our main window
  50. //IDirectDraw7 Pointer
  51. LPDIRECTDRAW7 lpdd=NULL;
  52. //display mode structure
  53. struct DisplayMode
  54. {
  55.     DWORD dwWidth;
  56.     DWORD dwHeight;
  57.     DWORD dwBPP;
  58. };
  59. //display mode enumeration variables
  60. DWORD dwDisplayModeCount=0;
  61. DisplayMode* DisplayModeList=NULL;
  62.  
  63. //gdicanvas
  64. CGDICanvas gdicBall;
  65.  
  66. //surfaces
  67. LPDIRECTDRAWSURFACE7 lpddsPrime=NULL;
  68. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  69. LPDIRECTDRAWSURFACE7 lpddsBall=NULL;
  70.  
  71. //clipper
  72. LPDIRECTDRAWCLIPPER lpddclip=NULL;
  73.  
  74. //size of the display
  75. DWORD dwDisplayWidth=0;
  76. DWORD dwDisplayHeight=0;
  77.  
  78. //position of the ball
  79. POINT ptBallPosition[2];
  80. POINT ptLastPosition[2][2];
  81. //velocity of the ball
  82. POINT ptBallVelocity[2];
  83.  
  84. //paused mode
  85. bool bPaused=false;
  86.  
  87. //sound manager
  88. LPDIRECTSOUND lpds;
  89.  
  90. //buffers
  91. LPDIRECTSOUNDBUFFER lpdsb[2];
  92.  
  93. //////////////////////////////////////////////////////////////////////////////
  94. //WINDOWPROC
  95. //////////////////////////////////////////////////////////////////////////////
  96. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  97. {
  98.     //which message did we get?
  99.     switch(uMsg)
  100.     {
  101.     case WM_ACTIVATEAPP:
  102.         {
  103.             if(wParam)
  104.             {
  105.                 if(bPaused)
  106.                 {
  107.                     //being activated
  108.                     bPaused=false;
  109.  
  110.                     //restore all surfaces
  111.                     lpdd->RestoreAllSurfaces();
  112.  
  113.                     //clear out back buffer
  114.                     DDBLTFX ddbltfx;
  115.                     DDBLTFX_ColorFill(&ddbltfx,0);
  116.                     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
  117.  
  118.                     //reload ball images
  119.                     LPDDS_ReloadFromFile(lpddsBall,"IsoHex6_4.bmp");
  120.                 }
  121.             }
  122.             else
  123.             {
  124.                 //being deactivated
  125.                 bPaused=true;
  126.             }
  127.         }break;
  128.     case WM_KEYDOWN:
  129.         {
  130.             //check for escape key
  131.             if(wParam==VK_ESCAPE)
  132.             {
  133.                 DestroyWindow(hWndMain);
  134.             }
  135.  
  136.             return(0);//handled message
  137.         }break;
  138.     case WM_DESTROY://the window is being destroyed
  139.         {
  140.  
  141.             //tell the application we are quitting
  142.             PostQuitMessage(0);
  143.  
  144.             //handled message, so return 0
  145.             return(0);
  146.  
  147.         }break;
  148.     case WM_PAINT://the window needs repainting
  149.         {
  150.             //a variable needed for painting information
  151.             PAINTSTRUCT ps;
  152.             
  153.             //start painting
  154.             HDC hdc=BeginPaint(hwnd,&ps);
  155.  
  156.             /////////////////////////////
  157.             //painting code would go here
  158.             /////////////////////////////
  159.  
  160.             //end painting
  161.             EndPaint(hwnd,&ps);
  162.                         
  163.             //handled message, so return 0
  164.             return(0);
  165.         }break;
  166.     }
  167.  
  168.     //pass along any other message to default message handler
  169.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  170. }
  171.  
  172.  
  173. //////////////////////////////////////////////////////////////////////////////
  174. //WINMAIN
  175. //////////////////////////////////////////////////////////////////////////////
  176. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  177. {
  178.     //assign instance to global variable
  179.     hInstMain=hInstance;
  180.  
  181.     //create window class
  182.     WNDCLASSEX wcx;
  183.  
  184.     //set the size of the structure
  185.     wcx.cbSize=sizeof(WNDCLASSEX);
  186.  
  187.     //class style
  188.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  189.  
  190.     //window procedure
  191.     wcx.lpfnWndProc=TheWindowProc;
  192.  
  193.     //class extra
  194.     wcx.cbClsExtra=0;
  195.  
  196.     //window extra
  197.     wcx.cbWndExtra=0;
  198.  
  199.     //application handle
  200.     wcx.hInstance=hInstMain;
  201.  
  202.     //icon
  203.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  204.  
  205.     //cursor
  206.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  207.  
  208.     //background color
  209.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  210.  
  211.     //menu
  212.     wcx.lpszMenuName=NULL;
  213.  
  214.     //class name
  215.     wcx.lpszClassName=WINDOWCLASS;
  216.  
  217.     //small icon
  218.     wcx.hIconSm=NULL;
  219.  
  220.     //register the window class, return 0 if not successful
  221.     if(!RegisterClassEx(&wcx)) return(0);
  222.  
  223.     //create main window
  224.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  225.  
  226.     //error check
  227.     if(!hWndMain) return(0);
  228.  
  229.     //if program initialization failed, then return with 0
  230.     if(!Prog_Init()) return(0);
  231.  
  232.     //message structure
  233.     MSG msg;
  234.  
  235.     //message pump
  236.     for(;;)    
  237.     {
  238.         //look for a message
  239.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  240.         {
  241.             //there is a message
  242.  
  243.             //check that we arent quitting
  244.             if(msg.message==WM_QUIT) break;
  245.             
  246.             //translate message
  247.             TranslateMessage(&msg);
  248.  
  249.             //dispatch message
  250.             DispatchMessage(&msg);
  251.         }
  252.  
  253.         //run main game loop
  254.         Prog_Loop();
  255.     }
  256.     
  257.     //clean up program data
  258.     Prog_Done();
  259.  
  260.     //return the wparam from the WM_QUIT message
  261.     return(msg.wParam);
  262. }
  263.  
  264. //////////////////////////////////////////////////////////////////////////////
  265. //INITIALIZATION
  266. //////////////////////////////////////////////////////////////////////////////
  267. bool Prog_Init()
  268. {
  269.     lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
  270.  
  271.     //enumerate the displaymodes
  272.     dwDisplayModeCount=0;
  273.  
  274.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackCount);
  275.  
  276.     DisplayModeList=new DisplayMode[dwDisplayModeCount];
  277.     dwDisplayModeCount=0;
  278.  
  279.     lpdd->EnumDisplayModes(0,NULL,NULL,EnumModesCallbackList);
  280.  
  281.     //pick a display mode
  282.     DisplayMode TestMode;
  283.     TestMode.dwWidth=0;
  284.     TestMode.dwHeight=0;
  285.     TestMode.dwBPP=0;
  286.     DWORD index;
  287.     bool found=false;
  288.  
  289.     for(index=0;(index<dwDisplayModeCount);index++)
  290.     {
  291.         if(DisplayModeList[index].dwBPP==16)
  292.         {
  293.             if(DisplayModeList[index].dwWidth>TestMode.dwWidth)
  294.             {
  295.                 TestMode.dwWidth=DisplayModeList[index].dwWidth;
  296.                 TestMode.dwHeight=DisplayModeList[index].dwHeight;
  297.                 TestMode.dwBPP=DisplayModeList[index].dwBPP;
  298.                 found=true;
  299.             }
  300.         }
  301.     }
  302.  
  303.     if(!found)
  304.     {
  305.         return(false);
  306.     }
  307.  
  308.     //set the display mode
  309.     lpdd->SetDisplayMode(TestMode.dwWidth,TestMode.dwHeight,TestMode.dwBPP,0,0);
  310.     //keep display width and height in global variables
  311.     dwDisplayWidth=TestMode.dwWidth;
  312.     dwDisplayHeight=TestMode.dwHeight;
  313.  
  314.     //create the primary surface with a single back buffer
  315.     lpddsPrime=LPDDS_CreatePrimary(lpdd,1);
  316.  
  317.     //retrieve back buffer
  318.     lpddsBack=LPDDS_GetSecondary(lpddsPrime);
  319.  
  320.     //do an initial clearing out of the back buffer
  321.     DDBLTFX ddbltfx;
  322.     DDBLTFX_ColorFill(&ddbltfx,0);
  323.  
  324.     //do a color fill
  325.     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  326.  
  327.     //create the region
  328.     HRGN hrgn=CreateRectRgn(0,0,dwDisplayWidth,dwDisplayHeight);
  329.  
  330.     //set up clipper
  331.     lpddclip=LPDDCLIP_Create(lpdd,hrgn);
  332.  
  333.     //delete region
  334.     DeleteObject(hrgn);
  335.  
  336.     //attach clipper
  337.     lpddsBack->SetClipper(lpddclip);
  338.  
  339.     //load in the ball image
  340.     gdicBall.Load(NULL,"IsoHex8_2.bmp");
  341.  
  342.     //create an offscreen surface to contain the ball
  343.     lpddsBall=LPDDS_LoadFromFile(lpdd,"IsoHex8_2.bmp");
  344.  
  345.     //create a black color key
  346.     LPDDS_SetSrcColorKey(lpddsBall,0);
  347.  
  348.     //initialize ball position and velocity
  349.     ptBallPosition[0].x=0;
  350.     ptBallPosition[0].y=0;
  351.     ptLastPosition[0][0].x=0;
  352.     ptLastPosition[0][0].y=0;
  353.     ptLastPosition[0][1].x=0;
  354.     ptLastPosition[0][1].y=0;
  355.     ptBallPosition[1].x=0;
  356.     ptBallPosition[1].y=0;
  357.     ptLastPosition[1][0].x=0;
  358.     ptLastPosition[1][0].y=0;
  359.     ptLastPosition[1][1].x=0;
  360.     ptLastPosition[1][1].y=0;
  361.  
  362.     ptBallVelocity[0].x=(rand()&7)+1;
  363.     ptBallVelocity[0].y=(rand()&7)+1;
  364.     ptBallVelocity[1].x=(rand()&7)+1;
  365.     ptBallVelocity[1].y=(rand()&7)+1;
  366.  
  367.     //load wav file
  368.     CWAVLoader wav;
  369.  
  370.     wav.Load("bounce.wav");
  371.  
  372.     //set up sounds
  373.     DirectSoundCreate(NULL,&lpds,NULL);
  374.  
  375.     //set coop level
  376.     lpds->SetCooperativeLevel(hWndMain,DSSCL_NORMAL);
  377.  
  378.  
  379.     //set up buffer description
  380.     DSBUFFERDESC dsbd;
  381.     memset(&dsbd,0,sizeof(DSBUFFERDESC));
  382.  
  383.     //size
  384.     dsbd.dwSize=sizeof(DSBUFFERDESC);
  385.  
  386.     //flags
  387.     dsbd.dwFlags=DSBCAPS_LOCSOFTWARE;
  388.  
  389.     //length and sound format
  390.     dsbd.dwBufferBytes=wav.GetLength();
  391.     dsbd.lpwfxFormat=wav.GetFormat();
  392.  
  393.     //create buffer
  394.     lpds->CreateSoundBuffer(&dsbd,&lpdsb[0],NULL);
  395.  
  396.     DWORD buflen,buflen2;
  397.     void* bufptr;
  398.  
  399.     //lock entire buffer
  400.     lpdsb[0]->Lock(0,0,&bufptr,&buflen,NULL,&buflen2,DSBLOCK_ENTIREBUFFER);
  401.     
  402.     //copy from wave loader to sound buffer
  403.     memcpy(bufptr,wav.GetData(),wav.GetLength());
  404.  
  405.     //unlock the buffer
  406.     lpdsb[0]->Unlock(bufptr,buflen,NULL,buflen2);
  407.  
  408.     //duplicate the sound
  409.     lpds->DuplicateSoundBuffer(lpdsb[0],&lpdsb[1]);
  410.  
  411.     return(true);//return success
  412. }
  413.  
  414. //////////////////////////////////////////////////////////////////////////////
  415. //CLEANUP
  416. //////////////////////////////////////////////////////////////////////////////
  417. void Prog_Done()
  418. {    
  419.     //clean up sounds
  420.     if(lpdsb[1])
  421.     {
  422.         lpdsb[1]->Release();
  423.         lpdsb[1]=NULL;
  424.     }
  425.  
  426.     if(lpdsb[0])
  427.     {
  428.         lpdsb[0]->Release();
  429.         lpdsb[0]=NULL;
  430.     }
  431.  
  432.     //clean up sound manager
  433.     if(lpds)
  434.     {
  435.         lpds->Release();
  436.         lpds=NULL;
  437.     }
  438.  
  439.     //clean up clipper
  440.     LPDDCLIP_Release(&lpddclip);
  441.  
  442.     //clean up ball surface
  443.     LPDDS_Release(&lpddsBall);
  444.         
  445.     //clean up primary surface(this will clean up the back buffer, also)
  446.     LPDDS_Release(&lpddsPrime);
  447.  
  448.     //clean up the dd pointer
  449.     LPDD_Release(&lpdd);
  450.  
  451.     //clean up gdicanvas
  452.     gdicBall.Destroy();
  453.  
  454.     //get rid of enumeration stuff
  455.     delete [] DisplayModeList;
  456. }
  457.  
  458. //////////////////////////////////////////////////////////////////////////////
  459. //MAIN GAME LOOP
  460. //////////////////////////////////////////////////////////////////////////////
  461. void Prog_Loop()
  462. {
  463.     //if paused, return without doing anything
  464.     if(bPaused) return;
  465.  
  466.     int index;
  467.  
  468.     for(index=0;index<2;index++)
  469.     {
  470.  
  471.     //set up rectangle for filling
  472.     RECT rcFill;
  473.     SetRect(&rcFill,ptLastPosition[index][0].x,ptLastPosition[index][0].y,ptLastPosition[index][0].x+gdicBall.GetWidth(),ptLastPosition[index][0].y+gdicBall.GetHeight());
  474.  
  475.     //set up a ddbltfx
  476.     DDBLTFX ddbltfx;
  477.     DDBLTFX_ColorFill(&ddbltfx,0);
  478.  
  479.     //blt the color fill to the back buffer
  480.     lpddsBack->Blt(&rcFill,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  481.     }
  482.  
  483.     for(index=0;index<2;index++)
  484.     {
  485.     //set up source and destination rects for blitting the ball
  486.     RECT rcSrc;
  487.     RECT rcDst;
  488.  
  489.     SetRect(&rcSrc,0,0,gdicBall.GetWidth(),gdicBall.GetHeight());
  490.     CopyRect(&rcDst,&rcSrc);
  491.     OffsetRect(&rcDst,ptBallPosition[index].x,ptBallPosition[index].y);
  492.  
  493.     //blit the ball
  494.     lpddsBack->Blt(&rcDst,lpddsBall,&rcSrc,DDBLT_WAIT | DDBLT_KEYSRC, NULL);
  495.  
  496.     //copy current position of ball to old position
  497.     ptLastPosition[index][0]=ptLastPosition[index][1];
  498.     ptLastPosition[index][1]=ptBallPosition[index];
  499.  
  500.     //move the ball
  501.     ptBallPosition[index].x+=ptBallVelocity[index].x;
  502.     ptBallPosition[index].y+=ptBallVelocity[index].y;
  503.  
  504.     //bounds checking
  505.     //left side
  506.     if(ptBallPosition[index].x<=0)
  507.     {
  508.         ptBallVelocity[index].x=abs(ptBallVelocity[index].x);
  509.         lpdsb[index]->Play(0,0,0);
  510.     }
  511.     //top side
  512.     if(ptBallPosition[index].y<=0)
  513.     {
  514.         ptBallVelocity[index].y=abs(ptBallVelocity[index].y);
  515.         lpdsb[index]->Play(0,0,0);
  516.     }
  517.     //right side
  518.     if(ptBallPosition[index].x>=(int)dwDisplayWidth-gdicBall.GetWidth())
  519.     {
  520.         ptBallVelocity[index].x=-abs(ptBallVelocity[index].x);
  521.         lpdsb[index]->Play(0,0,0);
  522.     }
  523.     //bottom side
  524.     if(ptBallPosition[index].y>=(int)dwDisplayHeight-gdicBall.GetHeight())
  525.     {
  526.         ptBallVelocity[index].y=-abs(ptBallVelocity[index].y);
  527.         lpdsb[index]->Play(0,0,0);
  528.     }
  529.     }
  530.     //flip surfaces
  531.     lpddsPrime->Flip(NULL,DDFLIP_WAIT);
  532. }
  533.  
  534. //enumeration-count
  535. HRESULT WINAPI EnumModesCallbackCount(
  536.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  537.   LPVOID lpContext                   
  538. )
  539. {
  540.     //increment the count variable
  541.     dwDisplayModeCount++;
  542.  
  543.     //continue the enumeration
  544.     return(DDENUMRET_OK);
  545. }
  546.  
  547. //enumeration-list
  548. HRESULT WINAPI EnumModesCallbackList(
  549.   LPDDSURFACEDESC2 lpDDSurfaceDesc,  
  550.   LPVOID lpContext                   
  551. )
  552. {
  553.     //copy applicable information to the list
  554.     DisplayModeList[dwDisplayModeCount].dwWidth=lpDDSurfaceDesc->dwWidth;
  555.     DisplayModeList[dwDisplayModeCount].dwHeight=lpDDSurfaceDesc->dwHeight;
  556.     DisplayModeList[dwDisplayModeCount].dwBPP=lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount;
  557.  
  558.     //increment the count variable
  559.     dwDisplayModeCount++;
  560.  
  561.     //continue the enumeration
  562.     return(DDENUMRET_OK);
  563. }
  564.